/*
 * Group:PrePool K9-357 
 * 8/2010
 */
package util;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import screen.Screen;
import corewa.CoreWa;
import event.Event;

public class ConfigUtil {
	static final Logger LOG = Logger.getLogger("ConfigUtil");

	/**
	 * @param file
	 *            inputStream of OnlineDictConfig.xml file
	 * @return a CoreWa's instance
	 */
	public static CoreWa parse(InputStream file) {
		CoreWa confInfo = new CoreWa();
		SAXParserFactory spFactory = SAXParserFactory.newInstance();

		try {
			SAXParser parser = spFactory.newSAXParser();
			parser.parse(file, new MyHandler(confInfo));
		} catch (Exception ex) {
			LOG.info(ex);
		}
		return confInfo;
	}

	/**
	 * @param resource
	 *            OnlineDictConfig.xml file's URI
	 * @return
	 */
	public static CoreWa parse(String resource) {
		InputStream is = null;

		try {
			is = new FileInputStream(resource);
		} catch (FileNotFoundException e) {
		}
		return parse(is);
	}
}

class MyHandler extends DefaultHandler {
	static final Logger LOG = Logger.getLogger("MyHandler");
	private CoreWa confInfo;
	// Temporary members
	private String screenId;
	private String controlClass;
	private String inputPage;
	Screen screen;

	String viewScreen;
	String editScreen;
	String helpScreen;
	boolean reachViewScreen = false;
	boolean reachEditScreen = false;
	boolean reachHelpScreen = false;

	private Map<String, Event> eventMap;

	/**
	 * @param confInfo
	 *            CoreWa's instance for reference
	 */
	public MyHandler(CoreWa confInfo) {
		this.confInfo = confInfo;
	}

	/**
	 * Processing tag of configuration file.
	 */
	@Override
	public void startElement(String url, String name, String qname,
			Attributes attr) throws SAXException {

		if ("view-screen".equals(qname)) {

			reachViewScreen = true;
		} else if ("edit-screen".equals(qname)) {
			reachEditScreen = true;
		} else if ("help-screen".equals(qname)) {
			reachHelpScreen = true;
		} else if ("screen".equals(qname)) { // reach to note screen
			// get screen id by attribute "id"
			screenId = attr.getValue("id");
			controlClass = attr.getValue("control");
			inputPage = attr.getValue("input");
			// Prepare screen
			screen = new Screen(screenId, controlClass, inputPage);
			// Prepare map of event
			eventMap = new HashMap<String, Event>();
		} else if ("event".equals(qname)) { // reach to note event
			Event event;
			String eventId = attr.getValue("id");
			String procId = attr.getValue("procId");
			String nextScrId = attr.getValue("nextScreen");
			event = new Event(eventId, procId, nextScrId);
			eventMap.put(eventId, event);
		}
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		String st = new String(ch, start, length);
		if (reachViewScreen) {
			confInfo.setViewScreen(st);
			reachViewScreen = false;
		} else if (reachEditScreen) {
			confInfo.setEditScreen(st);
			reachEditScreen = false;
		} else if (reachHelpScreen) {
			confInfo.setHelpScreen(st);
			reachHelpScreen = false;
		}
	}

	@Override
	public void endElement(String uri, String name, String qname)
			throws SAXException {
		if ("screen".equals(qname)) { // reach to end note screen
			// Add the screen information into the list
			screen.setEvents(eventMap);
			confInfo.addScreen(screen);
		}
	}
}